#include "windowholderui.h"
#include "ui_windowholderui.h"
#include "customproxy.h"


#include <optra/common/proxy.h>
#include "zonesmanager.h"
#include "optrzone.h"
#include "testwindow.h"
#include "scene.h"
#include <QtGui>
#include <QGLWidget>
#include <QtOpenGL>

#ifndef GL_MULTISAMPLE
#define GL_MULTISAMPLE  0x809D
#endif


O_Z;
#define optra() OZ

extern Optra::Proxy* proxy;
extern ZonesManager* zmanager;

WindowHolderUi::WindowHolderUi(QWidget *parent, GuiWindow* holder) :
        GuiWindow(parent),
        ui(new Ui::WindowHolderUi), holder_(holder), states(NULL)
{
    ui->setupUi(this);
    ui->graphicsView->setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers)));
    ui->graphicsView->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);

    scene_ = new Scene();

    // ui->graphicsView->setParent(NULL);
    ui->graphicsView->setScene(new Scene);

    //ui->graphicsView->show();

    //    testWindow()->show();
    //
    //    connect(ui->testBt, SIGNAL(clicked()), this, SLOT(testState()));
    //
    //    current_ = -1;
    //
    //    scene_ = new QGraphicsScene(-500, -500, 500, 500);
    //     scene_->setStickyFocus(true);
    //
    //
    //    states = new QStateMachine(this);
    //    rootState = new QState;
    //    baseState = new QState(rootState);
    //    centeredState = new QState(rootState);
    //    randomState = new QState(rootState);
    //
    //    ellipseState = new QState(rootState);
    //    figure8State = new QState(rootState);
    //
    //    tiledState = new QState(rootState);
    //
    //
    //    ui->graphicsView->scale(0.6, 0.6);
    //    ui->graphicsView->setRenderHints(ui->graphicsView->renderHints() | QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
    ////    ui->graphicsView->setBackgroundBrush(QPixmap(":/images/wallpaper"));
    //    ui->graphicsView->setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
    //
    //    ui->graphicsView->setCacheMode(QGraphicsView::CacheBackground);
    //    ui->graphicsView->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
    //
    if (holder != NULL){
        CustomProxy* cp = new CustomProxy(0, Qt::ToolTip);
        cp->setWidget(holder);
        items_.append(cp);
        scene_->addItem(cp);
        adjustSize();
    }
    //
    //    ui->graphicsView->setScene(scene_);
    //
    //    // ui->graphicsView->translate(-250, -250);
    //    scene_->addLine(0, 0, scene_->sceneRect().width(), 100);
    //    scene_->addText(QString::number(scene_->sceneRect().width()));
    //
    //    scene_->addRect(scene_->sceneRect());
    //
    //    states->addState(rootState);
    //    states->setInitialState(rootState);
    //    rootState->setInitialState(baseState);
}

WindowHolderUi::~WindowHolderUi()
{
    delete scene_;
    delete ui;
}

void WindowHolderUi::testState()
{
    qDebug() << "Test";
    //ui->graphicsView->rotate(45);
}

QPointF WindowHolderUi::centerPos(QGraphicsProxyWidget* w)
{    
    QPointF cpt = scene_->sceneRect().center();
    QSizeF ws = w->size() / 2;
    return QPointF(cpt.x() - ws.width(), cpt.y() - ws.height());
}

void WindowHolderUi::centerWidget(QGraphicsProxyWidget* w)
{
    w->setPos(centerPos(w));
}

void WindowHolderUi::adjustSize()
{
    QGraphicsProxyWidget* h = items_.at(0);
    if (h == NULL){
        return;
    }

    QSize s1 = h->boundingRect().size().toSize();// size();
    ui->graphicsView->resize(s1);
    s1 +=  QSize(20, 20);
    resize(s1);

    //QSize s2 = h->frameSize() / 2;
    //s1 = ui->graphicsView->size() / 2;
    //h->move(-(s1.width() - s2.width()), -(s1.height() - s2.height()));
    //scene_->items().at(0)->setTransformOriginPoint();
    //centerWidget(h);

}

void WindowHolderUi::single(int i)
{    
    if (items_.isEmpty()){
        return;
    }

    if (i < 0){
        i = current_;
    }    

    view(i);
    QGraphicsProxyWidget* gpw = items_.at(i);
    //centerWidget(items_[0]);
    //    gpw->setGeometry(ui->graphicsView->geometry());
    //  ui->graphicsView->fitInView(gpw);
}

void WindowHolderUi::grid()
{
    // ui->graphicsView->scale(0.5, 0.5);

}

void WindowHolderUi::addWidgetProxy(QGraphicsProxyWidget* proxy)
{
    proxy->setFlag(QGraphicsItem::ItemIsMovable);
    proxy->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
    proxy->setFocusPolicy(Qt::StrongFocus);
    scene_->addItem(proxy);
    items_.append(proxy);    
    // centerWidget(proxy);
    QRectF rf = scene_->sceneRect();     
    proxy->setPos(10, 10);
    //  proxy->setGeometry(rf);
    //  proxy->setPos(scene_->sceneRect().topRight());
    // setupAnimation();
}

void WindowHolderUi::changeEvent(QEvent *e)
{
    QWidget::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}

void WindowHolderUi::selectionChanged()
{

}

void WindowHolderUi::view(int i)
{

    if (i < 0 || current_ == i || i > items_.count()){
        optra()->debug(QString("Skiping View (current:%1, new:%2)").arg(current_).arg(i));
        return;
    }

    bool forward = (i > current_);


    QGraphicsProxyWidget* v = items_.at(i);

    //QSequentialAnimationGroup* group = new QSequentialAnimationGroup(this);
    QParallelAnimationGroup* group = new QParallelAnimationGroup(this);

    QRectF pg = v->geometry();
    if (current_ > -1){
        QGraphicsProxyWidget* cv = items_.at(current_);        


        QPropertyAnimation *anim = new QPropertyAnimation(cv->toGraphicsObject(), "pos");
        anim->setDuration(250);//750 + i * 25);
        QPointF pp = scene_->sceneRect().topLeft();
        anim->setStartValue(pp);

        pg = cv->geometry();
        pg.moveLeft(pp.x() + pg.left());
        anim->setEndValue(pp);
        //anim->setEasingCurve(QEasingCurve::InOutBack);
        group->addAnimation(anim);


        pg = cv->geometry();
    }

    QPropertyAnimation* anim = new QPropertyAnimation(v->toGraphicsObject(), "pos");
    anim->setDuration(250);//750 + i * 25);

    QPointF pp = scene_->sceneRect().topRight();
    anim->setStartValue(scene_->sceneRect().topRight());

    pp = scene_->sceneRect().topLeft();
    anim->setEndValue(scene_->sceneRect().topLeft());
    //anim->setEasingCurve(QEasingCurve::InOutBack);
    group->addAnimation(anim);

    group->start();

    //WindowHolderUi*gw = (WindowHolderUi*)v->widget();
    //gw->holder()->update();

    //centerWidget(v);
    //scene_->setActiveWindow((QGraphicsWidget*)v);
    //ui->graphicsView->ensureVisible(v);
    // ui->graphicsView->centerOn(v);
    // v->setActive(true);

    QRectF rf = scene_->sceneRect();
    // v->setGeometry(rf);// tPos(0, 0);
    optra()->trace(QString("current view:%1. previous:%2").arg(i).arg(current_));
    current_ = i;

}

void WindowHolderUi::next()
{

    if (current_ + 1 >= items_.count()){
        view(0);
        return;
    }

    // view(current_ + 1);
    //single(current_);

}

void WindowHolderUi::previous()
{

    if (current_ - 1 < 0){
        view(items_.count() - 1);
        return;
    }

    // single(current_ - 1);

}

void WindowHolderUi::resizeEvent(QResizeEvent * event)
{
    //single();
    GuiWindow::resizeEvent(event);
}


void WindowHolderUi::setupAnimation()
{
    //TODO: check memory here for leeeaks (QT Ownership)
    states->stop();
    delete states;
    states = new QStateMachine(this);

    rootState = new QState;
    baseState = new QState(rootState);
    centeredState = new QState(rootState);
    randomState = new QState(rootState);
    ellipseState  = new QState(rootState);
    tiledState  = new QState(rootState);

    states->addState(rootState);
    states->setInitialState(rootState);
    rootState->setInitialState(baseState);

    QParallelAnimationGroup *group = new QParallelAnimationGroup;

    QSizeF rc = scene_->sceneRect().size();
    rc *= 2;


    int line = 0;
    int column = 0;
    float fcount = (float)items_.size();
    for(int i = 0; i < items_.size(); i++){
        QGraphicsProxyWidget* pw = items_.at(i);
        QGraphicsObject* go = pw->toGraphicsObject();

        baseState->assignProperty(go, "rotation",0.0);
        baseState->assignProperty(go, "pos", go->pos());
        baseState->assignProperty(go, "size", pw->size());

        centeredState->assignProperty(go, "pos", centerPos(pw));

        float arc = (float)i / (float)(items_.size());
        ellipseState->assignProperty(go, "rotation", (360.0 / items_.size() - 1) * i);
        ellipseState->assignProperty(go, "pos",  QPointF(cos(arc * 6.28) * 250,
                                                         sin(arc * 6.28) * 250));

        QSizeF sf = pw->boundingRect().size();
        sf.scale(50, 50, Qt::KeepAspectRatio);
        tiledState->assignProperty(go, "size", sf);
        tiledState->assignProperty(go, "pos", QPointF((column + 10), line * sf.height()));
        column += sf.width() + 10;

        randomState->assignProperty(go, "pos",  QPointF((qrand() % 1000) - 500.0, (qrand() % 1000) - 500.0));


        QPropertyAnimation *anim = new QPropertyAnimation(go, "pos");
        anim->setDuration(750 + i * 25);
        anim->setEasingCurve(QEasingCurve::InOutBack);
        group->addAnimation(anim);
    }

    QAbstractTransition *trans = rootState->addTransition(ui->testBt, SIGNAL(clicked()), randomState);
    trans->addAnimation(group);

    trans = randomState->addTransition(ui->testBt, SIGNAL(clicked()), centeredState);
    trans->addAnimation(group);

    trans = centeredState->addTransition(ui->testBt, SIGNAL(clicked()), ellipseState);
    trans->addAnimation(group);

    trans = ellipseState->addTransition(ui->testBt, SIGNAL(clicked()), tiledState);
    trans->addAnimation(group);

    trans = tiledState->addTransition(ui->testBt, SIGNAL(clicked()), rootState);
    trans->addAnimation(group);

    states->start();
}
